package ai.restosuite.infrastructure.operation.work;

import camundajar.impl.com.google.gson.Gson;
import camundajar.impl.com.google.gson.JsonArray;
import groovy.lang.GroovyShell;
import org.apache.commons.lang3.StringUtils;
import org.camunda.bpm.engine.*;
import org.camunda.bpm.engine.form.StartFormData;
import org.camunda.bpm.engine.form.TaskFormData;
import org.camunda.bpm.engine.history.HistoricProcessInstance;
import org.camunda.bpm.engine.history.HistoricTaskInstance;
import org.camunda.bpm.engine.repository.ProcessDefinition;
import org.camunda.bpm.engine.runtime.ProcessInstance;
import org.camunda.bpm.engine.runtime.ProcessInstanceQuery;
import org.camunda.bpm.engine.task.Task;
import org.camunda.bpm.engine.task.TaskQuery;
import org.camunda.bpm.engine.variable.VariableMap;
import org.h2.util.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.io.*;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@RestController
public class WorkController {

    @Autowired
    RuntimeService runtimeService;

    @Autowired
    TaskService taskService;

    @Autowired
    HistoryService historyService;

    @Autowired
    IdentityService identityService;

    @Autowired
    RepositoryService repositoryService;

    @Autowired
    FormService formService;

    /**
     * 发起流程
     * @param processDefineKey processDefineKey
     * @param startUser startUser
     * @return String
     */
    @PostMapping("/startProcessInstance")
    public String startProcessInstance(@RequestParam("processDefineKey")String processDefineKey,@RequestParam("businessKey") String businessKey,
                                       @RequestParam("startUser")String startUser, @RequestBody Map<String, Object> map) {
        /**
         * 1.先判断用户是否在系统中，不在就返回用户不存在
         */


        /**
         * 2.封装参数
         */
        map.put("startUser", StringUtils.isBlank(startUser)?"admiin":startUser);

       //发起流程
        ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(processDefineKey,businessKey, map);

        return processInstance.getProcessInstanceId();
    }

    /**
     * 提交任务
     * @param taskId taskId
     * @param map map
     * @return String
     */
    @PostMapping("/completeProcessInstance")
    public String completeProcessInstance(@RequestParam("taskId")String taskId,
                                       @RequestBody Map<String, Object> map) {
        //需要判断该任务状态+异常捕获，只有create状态的，才能审批（已删除的或已完成的，不能再次审批）
        taskService.complete(taskId,map);
        return "ok";
    }


    /**
     * 查询我的待办任务
     * @param userId
     * @return List
     */
    @GetMapping("/selectOwnerToDoTask")
    public String selectOwnerToDoTask(@RequestParam("userId")String userId) {
        List<Task> list = taskService.createTaskQuery()
                .taskAssignee(userId)
                .list();
        Gson gson = new Gson();
        return gson.toJson(list);
    }

    /**
     * 查询我的已办任务
     * @param userId
     * @return List
     */
    @GetMapping("/selectOwnerTask")
    public String selectOwnerTask(@RequestParam("userId")String userId) {
        List<HistoricTaskInstance> list = historyService.createHistoricTaskInstanceQuery()
                .taskAssignee(userId)
                .finished()
                .list();
        Gson gson = new Gson();
        return gson.toJson(list);
    }

    /**
     * 根据实例id 查询任务
     */
    @GetMapping("/selectTaskByInstanceId")
    public String selectTaskByInstanceId(@RequestParam("instanceId")String instanceId) {
        /**
         * 查询指定实例id下，未完成的task
         * historyService.createHistoricTaskInstanceQuery().processInstanceId(instanceId).unfinished().list()
         * 查询指定实例id下，已完成的task
         * historyService.createHistoricTaskInstanceQuery().processInstanceId(instanceId).finished().list()
         * 查询指定实例id下，已完成的流程中的所有task
         * historyService.createHistoricTaskInstanceQuery().processInstanceId(instanceId).processFinished().list()
         * 查询指定实例id下，未完成的流程中的所有task
         * historyService.createHistoricTaskInstanceQuery().processInstanceId(instanceId).processUnfinished().list()
         *
         * 注意：processFinished/processUnfinished 是流程角度判断是否完成； unfinished/finished 是任务角度判断是否完成
         */
        List<HistoricTaskInstance> list = historyService.createHistoricTaskInstanceQuery().processInstanceId(instanceId).list();
        Gson gson = new Gson();
        return gson.toJson(list);
    }

    /**
     * 根据taskid 查询任务
     */
    @GetMapping("/selectTaskById")
    public String selectTaskById(@RequestParam("userId")String userId, @RequestParam("taskId")String taskId) {
        HistoricTaskInstance historicTaskInstance = historyService.createHistoricTaskInstanceQuery().taskId(taskId).singleResult();
        Gson gson = new Gson();
        return gson.toJson(historicTaskInstance);
    }

    /**
     * 查询我发起的任务
     */
    @GetMapping("/selectTaskMyStart")
    public String selectTaskMyStart(@RequestParam("userId")String userId) {
        List<HistoricProcessInstance> list = historyService.createHistoricProcessInstanceQuery().startedBy(userId).list();
        Gson gson = new Gson();
        return gson.toJson(list);
    }

    /**
     * 委派任务
     * 任务委派是委派人将当前的任务交给被委派人进行审批，解决任务后又重新回到委派人身上，当被委派人直接完成任务时，任务就不会回到委派人。
     */
    @GetMapping("/delegateTask")
    public String delegateTask(@RequestParam("taskId")String taskId, @RequestParam("userId")String userId) {
        taskService.delegateTask(taskId, userId);

        /**
         * 委派人查询任务

        List<Task> list = taskService.createTaskQuery()
                .taskOwner(userId)
                .list();

         被委托人解决任务

         taskService.resolveTask(taskId);
         */
        return "ok";
    }

    /**
     * 转办任务
     */
    @GetMapping("/setAssignee")
    public String setAssignee(@RequestParam("taskId")String taskId, @RequestParam("userId")String userId, @RequestParam("assignee")String assignee) {
        identityService.setAuthenticatedUserId(userId);
        //任务转办
        taskService.setAssignee(taskId,assignee);
        return "ok";
    }

    /**
     * 获取流程图xml
     * 前端需要使用 bpmn-js 来绘制流程图
     * @param processDefinitionId processDefinitionId
     */
    @GetMapping("/getProcessXml")
    public String getProcessXml(@RequestParam("processDefinitionId")String processDefinitionId) throws IOException {
        ProcessDefinition processDefinition = repositoryService.getProcessDefinition(processDefinitionId);

        InputStream b = repositoryService.getResourceAsStream(processDefinition.getDeploymentId(), processDefinition.getResourceName());
        BufferedInputStream bis = new BufferedInputStream(b);
        ByteArrayOutputStream buf = new ByteArrayOutputStream();
        int result = bis.read();
        while(result != -1) {
            buf.write((byte) result);
            result = bis.read();
        }
        bis.close();
        String str = buf.toString("UTF-8");
        /**
         * 若需要查询当前流程审批的进度，可以结合根据实例id查询所有未完成的userTask，根据task状态来判断当前active节点（taskState=create状态，为待审批节点）
         * historyService.createHistoricTaskInstanceQuery().processInstanceId(instanceId).unfinished.list()
         */
        return str;
    }

    /**
     * 获取任务表单
     * @param taskId taskId
     */
    @GetMapping("/getTaskForm")
    public String getTaskForm(@RequestParam("taskId")String taskId) throws IOException {
        //TaskFormData
        TaskFormData taskFormData = formService.getTaskFormData(taskId);

        //表单模板
        InputStream deployedTaskForm = formService.getDeployedTaskForm(taskId);
        BufferedInputStream bis = new BufferedInputStream(deployedTaskForm);
        ByteArrayOutputStream buf = new ByteArrayOutputStream();
        int result = bis.read();
        while(result != -1) {
            buf.write((byte) result);
            result = bis.read();
        }
        bis.close();
        String str = buf.toString("UTF-8");

        //表单数据
        VariableMap taskFormVariables = formService.getTaskFormVariables(taskId);

        Map<String ,Object> ret = new HashMap<>();
        ret.put("key",taskFormData.getFormKey());
        ret.put("form", str);
        ret.put("data", taskFormVariables);
        Gson gson = new Gson();
        return gson.toJson(ret);
    }

    /**
     * 获取流程启动任务表单
     * @param processDefinitionId processDefinitionId
     */
    @GetMapping("/getStartForm")
    public String getStartForm(@RequestParam("processDefinitionId")String processDefinitionId) throws IOException {
        //TaskFormData
        StartFormData startFormData = formService.getStartFormData(processDefinitionId);

        //表单模板
        InputStream deployedStartForm = formService.getDeployedStartForm(processDefinitionId);
        BufferedInputStream bis = new BufferedInputStream(deployedStartForm);
        ByteArrayOutputStream buf = new ByteArrayOutputStream();
        int result = bis.read();
        while(result != -1) {
            buf.write((byte) result);
            result = bis.read();
        }
        bis.close();
        String str = buf.toString("UTF-8");

        //表单数据
        VariableMap taskFormVariables = formService.getStartFormVariables(processDefinitionId);

        Map<String ,Object> ret = new HashMap<>();
        ret.put("key",startFormData.getFormKey());
        ret.put("form", str);
        ret.put("data", taskFormVariables);
        Gson gson = new Gson();
        return gson.toJson(ret);
    }



    public static void main(String[] args) {
        // 创建GroovyShell实例
        GroovyShell shell = new GroovyShell();

        // 定义Groovy脚本
        String script = "import groovy.json.JsonOutput; def a = JsonOutput.toJson([name: 'John Doe', age: 42]) pritln ${a}";

        // 执行Groovy脚本
        Object result = shell.evaluate(script);

        // 输出结果
        System.out.println(result);
    }
}
